<!doctype html>
<html lang="en">
<head>
    <title>webgl house</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            color: #61443e;
            font-family:Monospace;
            font-size:13px;
            text-align:center;

            background-color: #aaccff;
            margin: 0px;
            overflow: hidden;
        }

        #info {
            color: #ffffff;
            position: absolute;
            top: 0px; width: 100%;
            padding: 5px;
        }

        a {

            color: yellow;
        }

        #oldie {
            background:rgb(0,0,50) !important;
            color:#fff !important;
        }

    </style>
</head>
<body>

<div id="container"></div>

<script src="http://derekliu.blog.51cto.com/attachment/201205/4479510_1336024306.jpg"></script>

<script src="http://derekliu.blog.51cto.com/attachment/201205/4479510_1336039846.jpg"></script>
<script src="http://derekliu.blog.51cto.com/attachment/201205/4479510_1336039876.jpg"></script>
<script src="http://blog.51cto.com/attachment/201205/4479510_1336021040.jpg"></script>
<video id="video" autoplay loop style="display:none">
    <source src="http://derekliu.blog.51cto.com/album/4479510/133601724210.jpg" type='video/ogg; codecs="theora, vorbis"'>
</video>
<script>

    if ( ! Detector.webgl ) {

        Detector.addGetWebGLMessage();
        document.getElementById( 'container' ).innerHTML = "";

    }

    var container, stats;

    var camera, controls, scene, renderer, projector;

    var mouse = new THREE.Vector2();

    var objects = [], SELECTED;

    var keyScale = 1;

    var mesh, texture, geometry, material;

    var worldWidth = 128, worldDepth = 128,
            worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2;

    var clock = new THREE.Clock();

    var tvvideo, tvtexture;
    init();
    animate();

    function init() {

        container = document.getElementById( 'container' );

        scene = new THREE.Scene();
        scene.fog = new THREE.FogExp2( 0xaaccff, 0.0007 );

        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 20000 );
        camera.position.x = 0;
        camera.position.y = 50;
        camera.position.z = 200;
        scene.add( camera );

        controls = new THREE.FirstPersonControls( camera );
        controls.movementSpeed = 300;
        controls.lookSpeed = 0.01
        controls.lon = 300;

        var light, object;

        scene.add( new THREE.AmbientLight( 0x777777 ) );

        var bedroomLight = new THREE.SpotLight( 0xffffff,1.2,600);
        bedroomLight.position.set( 180, 250, -350 );
        bedroomLight.target.position.set( 180, 20, -350 );
        bedroomLight.castShadow = true;
        bedroomLight.shadowDarkness = 0.3;
        bedroomLight.shadowBias = -0.0002;
        bedroomLight.shadowCameraNear = 750;
        bedroomLight.shadowCameraFar = 4000;
        bedroomLight.shadowCameraFov = 30;
        bedroomLight.shadowCameraVisible = false;
        scene.add( bedroomLight );

        var livingroomLight = new THREE.SpotLight( 0xffffff,1.2,600);
        livingroomLight.position.set( 340, 280, -760 );
        livingroomLight.target.position.set( 340, 20, -760 );
        livingroomLight.castShadow = true;
        livingroomLight.shadowDarkness = 0.3;
        livingroomLight.shadowBias = -0.0002;
        livingroomLight.shadowCameraNear = 750;
        livingroomLight.shadowCameraFar = 4000;
        livingroomLight.shadowCameraFov = 30;
        livingroomLight.shadowCameraVisible = false;
        scene.add( livingroomLight );

        var restroomLight = new THREE.SpotLight( 0xffffff,1.2,400);
        restroomLight.position.set( 90, 280, -650 );
        restroomLight.target.position.set( 90, 20, -650 );
        restroomLight.castShadow = true;
        restroomLight.shadowDarkness = 0.3;
        restroomLight.shadowBias = -0.0002;
        restroomLight.shadowCameraNear = 750;
        restroomLight.shadowCameraFar = 4000;
        restroomLight.shadowCameraFov = 30;
        restroomLight.shadowCameraVisible = false;
        scene.add( restroomLight );

        var kitchenroomLight = new THREE.SpotLight( 0xffffff,1.2,400);
        kitchenroomLight.position.set( 40, 280, -840 );
        kitchenroomLight.target.position.set( 40, 20, -840 );
        kitchenroomLight.castShadow = true;
        kitchenroomLight.shadowDarkness = 0.3;
        kitchenroomLight.shadowBias = -0.0002;
        kitchenroomLight.shadowCameraNear = 750;
        kitchenroomLight.shadowCameraFar = 4000;
        kitchenroomLight.shadowCameraFov = 30;
        kitchenroomLight.shadowCameraVisible = false;
        scene.add( kitchenroomLight );

        var baconLight = new THREE.SpotLight( 0xffffff,1.2,400);
        baconLight.position.set( 180, 280, -75 );
        baconLight.target.position.set( 180, 20, -75 );
        baconLight.castShadow = true;
        baconLight.shadowDarkness = 0.3;
        baconLight.shadowBias = -0.0002;
        baconLight.shadowCameraNear = 750;
        baconLight.shadowCameraFar = 4000;
        baconLight.shadowCameraFov = 30;
        baconLight.shadowCameraVisible = false;
        scene.add( baconLight );

        geometry = new THREE.PlaneGeometry( 20000, 20000, worldWidth - 1, worldDepth - 1 );
        geometry.dynamic = true;

        var i, j, il, jl;

        for ( i = 0, il = geometry.vertices.length; i < il; i ++ ) {
            var r = Math.sqrt(geometry.vertices[i].position.x*geometry.vertices[i].position.x + geometry.vertices[i].position.y*geometry.vertices[i].position.y);
            if( r> 9000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(2500,3000);
            }else if(r > 8000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(2100,2600);
            }else if(r > 7000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(1700,2200);
            }else if(r > 6000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(1300,1800);
            }else if(r > 5000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(900,1400);
            }else if(r > 4000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(500,1000);
            }else if(r > 3000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(100,600);
            }else if(r > 2000){
                geometry.vertices[ i ].position.z = THREE.Math.randInt(0,200);
            }else{
                geometry.vertices[ i ].position.z = THREE.Math.randInt(-20,20);
            }

        }

        geometry.computeFaceNormals();
        geometry.computeVertexNormals();

        var texture = THREE.ImageUtils.loadTexture( "http://derekliu.blog.51cto.com/album/4479510/133601723593.png" );
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.set( 100, 100 );

        material = new THREE.MeshBasicMaterial( { color: 0x0044ff, map: texture } );

        mesh = new THREE.Mesh( geometry, material );
        mesh.rotation.x = - 90 * Math.PI / 180;
        scene.add( mesh );

        addWall(scene);
        //tv
        tvvideo = document.getElementById( 'video' );
        tvtexture = new THREE.Texture( tvvideo );
        tvtexture.minFilter = THREE.LinearFilter;
        tvtexture.magFilter = THREE.LinearFilter;
        tvtexture.format = THREE.RGBFormat;
        var tvmaterials = [
            new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: tvtexture } ),
            new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: false, transparent: true, opacity: 0.1 } )
        ];
        object = THREE.SceneUtils.createMultiMaterialObject( new THREE.CubeGeometry( 1, 60, 96, 1, 5, 9,null,null,new THREE.UV(96,60)), tvmaterials );
        object.position.set( 202, 135+30, -(688+48) );
        scene.add( object );

        var loader = new THREE.JSONLoader(),
            callbackbigsofa   = function( geometry ) { createSceneCommon( geometry,  310, 20, -800, 80, 80, 80, 0, -1.57, 0) },
            callbackteatable   = function( geometry ) { createSceneCommon( geometry,  400, 20, -650, 3, 3, 3, 0, 1.57, 0) },
            callbackclothestree   = function( geometry ) { createSceneCommon( geometry,  460, 20, -850, 30, 30, 30, 0, 0, 0) },
            callbackkingbed   = function( geometry ) { createSceneCommon( geometry,  205, 20, -150, 2, 2, 2, 0, 1.57, 0) },
            callbacklivinglight   = function( geometry ) { createSceneCommon( geometry,  360, 300, -760, 0.1, 0.1, 0.1, 0, 0, 0) },
            callbackmakeupdesk   = function( geometry ) { createSceneCommon( geometry,  270, 20, -480, 3, 3, 3, 0, -1.57, 0) },
            callbackvanity   = function( geometry ) { createSceneCommon( geometry,  110, 20, -620, 50, 60, 50, 0, 1.57, 0) },
            callbackwc   = function( geometry ) { createSceneCommon( geometry,  100, 20, -550, 3, 3, 3, 0, 1.57, 0) },
            callbacktv   = function( geometry ) { createSceneCommon( geometry,  125, 120, -880, 0.6, 0.6, 0.6, 0, -1.57, 0) },
            callbackkitchen   = function( geometry ) { createSceneCommon( geometry,  170, 20, -830, 0.8, 0.8, 0.8, 0, 3.2, 0) },
            callbackfridge   = function( geometry ) { createSceneCommon( geometry,  -70, 20, -840, 0.7, 0.7, 0.7, 0, 0, 0) },
            callbackwashm   = function( geometry ) { createSceneCommon( geometry,  20, 20, -60, 1.2, 1.2, 1.2, 0, 0, 0) },
            callbackplant   = function( geometry ) { createSceneCommon( geometry,  320, 20, -40, 1.5, 3, 1.5, 0, 0, 0) },
            callbackwardrobe   = function( geometry ) { createSceneCommon( geometry,  -100, 20, -528, 0.55, 0.8, 0.8, 0, 0, 0) },
            callbackshower   = function( geometry ) { createSceneCommon( geometry,  59, 20, -795, 0.15, 0.25, 0.18, 0, -1.58, 0) },
            callbackaircondition   = function( geometry ) { createSceneCommon( geometry,  355, 298, -117, 1.2, 1.2, 1.2, 0, 1.57, 0) },
            callbackcurtain   = function( geometry ) { createSceneCommon( geometry,  20, 0, -148, 1.3, 1.9, 1.3, 0, 0, 0) };

        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336025015.jpg", callbackbigsofa );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336028720.jpg", callbackteatable );
        loader.load( ["http://derekliu.blog.51cto.com/attachment/201205/4479510_1336024973.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336024222.jpg"], callbackclothestree );
        loader.load( ["http://derekliu.blog.51cto.com/attachment/201205/4479510_1336026011.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336025786.jpg"], callbackkingbed );
        loader.load( ["http://derekliu.blog.51cto.com/attachment/201205/4479510_1336026951.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336026919.jpg"], callbacklivinglight );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336027131.jpg", callbackmakeupdesk );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336029000.jpg", callbackvanity );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336029212.jpg", callbackwc );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336028832.jpg", callbacktv );
        loader.load( ["http://derekliu.blog.51cto.com/attachment/201205/4479510_1336026696.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336026684.jpg"], callbackkitchen );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336025395.jpg", callbackfridge );
        loader.load( ["http://derekliu.blog.51cto.com/attachment/201205/4479510_1336027693.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336027541.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336027542.jpg","http://derekliu.blog.51cto.com/attachment/201205/4479510_1336027556.jpg"], callbackplant );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336029117.jpg", callbackwardrobe );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336028646.jpg", callbackshower );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336024717.jpg", callbackaircondition );
        loader.load( "http://derekliu.blog.51cto.com/attachment/201205/4479510_1336025312.jpg", callbackcurtain );

        object = new THREE.AxisHelper();
        object.position.set( -400, 50, 0 );
        object.scale.x = object.scale.y = object.scale.z = 2;
        scene.add( object );

        renderer = new THREE.WebGLRenderer( { clearColor: 0xaaccff, clearAlpha: 1 } );
        renderer.setSize( window.innerWidth, window.innerHeight );

        container.innerHTML = "";

        container.appendChild( renderer.domElement );

        stats = new Stats();
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.top = '0px';
        container.appendChild( stats.domElement );

        projector = new THREE.Projector();
        document.addEventListener( 'keyup', onDocumentKeyUp, false );
        document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    }

    function onDocumentMouseUp( event ) {
        event.preventDefault();
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
        mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

        var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
        projector.unprojectVector( vector, camera );

        var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
        var intersects = ray.intersectObjects( objects );

        if ( intersects.length > 0 ) {

            SELECTED = intersects[ 0 ].object;
            //alert(SELECTED.position.x +"," + SELECTED.position.y + "," + SELECTED.position.z);
        }
    }

    function onDocumentKeyUp ( event ) {
        event.preventDefault();
        if( event.keyCode == 13 /*ENTER*/){
            if( SELECTED ){
                alert(SELECTED.position.x +"," + SELECTED.position.y + "," + SELECTED.position.z);
                SELECTED = null;
            }
        }else if( event.keyCode == 86 /*V*/){
            var str = "Object List:\n";
            for(var i = 0; i < objects.length; i++ ){
                str = str + i + " : " + objects[i].position.x +"," + objects[i].position.y + "," + objects[i].position.z + "\n" ;
            }
            if( SELECTED ){
                str = str + "SELECTED: Position=[" + SELECTED.position.x +"," + SELECTED.position.y + "," + SELECTED.position.z + "]\n";
                str = str + "          Rotation=[" + SELECTED.rotation.x +"," + SELECTED.rotation.y + "," + SELECTED.rotation.z + "]\n";
                str = str + "          Scale=[" + SELECTED.scale.x +"," + SELECTED.scale.y + "," + SELECTED.scale.z + "]\n";
                str = str + "          keyScale = " + keyScale;
            }else{
                str = str + "SELECTED is null, please press Q to frezee the camera, then click mouse to select.\n";
            }
            var index = prompt(str,'0');
            if( index != null && index != "" ){
                if( !isNaN(parseFloat(index)) && index > 0 && index < objects.length ){
                    SELECTED = objects[index];
                }else{
                    alert("Your index is not correct.");
                }
            }
        }else if( event.keyCode == 191 /*?*/){
            alert("[SHIFT+]Y,H,N:change position\n[SHIFT+]U,J,M:change rotation\n[SHIFT+]I,K,<:change scale\n0,-,+:change key precision");
        }else{
            if( SELECTED ){
                if( event.keyCode == 89 && !event.shiftKey /*Y*/){
                    SELECTED.position.x += 10 * keyScale;
                }else if( event.keyCode == 89 && event.shiftKey /*SHIFT + Y*/){
                    SELECTED.position.x -= 10 * keyScale;
                }else if( event.keyCode == 72 && !event.shiftKey /*H*/){
                    SELECTED.position.y += 10 * keyScale;
                }else if( event.keyCode == 72 && event.shiftKey /*SHIFT + H*/){
                    SELECTED.position.y -= 10 * keyScale;
                }else if( event.keyCode == 78 && !event.shiftKey /*N*/){
                    SELECTED.position.z += 10 * keyScale;
                }else if( event.keyCode == 78 && event.shiftKey /*SHIFT + N*/){
                    SELECTED.position.z -= 10 * keyScale;
                }else if( event.keyCode == 85 && !event.shiftKey /*U*/){
                    SELECTED.rotation.x += 0.1 * keyScale;
                }else if( event.keyCode == 85 && event.shiftKey /*SHIFT + U*/){
                    SELECTED.rotation.x -= 0.1 * keyScale;
                }else if( event.keyCode == 74 && !event.shiftKey /*J*/){
                    SELECTED.rotation.y += 0.1 * keyScale;
                }else if( event.keyCode == 74 && event.shiftKey /*SHIFT + J*/){
                    SELECTED.rotation.y -= 0.1 * keyScale;
                }else if( event.keyCode == 77 && !event.shiftKey /*M*/){
                    SELECTED.rotation.z += 0.1 * keyScale;
                }else if( event.keyCode == 77 && event.shiftKey /*SHIFT + M*/){
                    SELECTED.rotation.z -= 0.1 * keyScale;
                }else if( event.keyCode == 73 && !event.shiftKey /*I*/){
                    SELECTED.scale.x += 0.1 * keyScale;
                }else if( event.keyCode == 73 && event.shiftKey /*SHIFT + I*/){
                    SELECTED.scale.x -= 0.1 * keyScale;
                }else if( event.keyCode == 75 && !event.shiftKey /*K*/){
                    SELECTED.scale.y += 0.1 * keyScale;
                }else if( event.keyCode == 75 && event.shiftKey /*SHIFT + K*/){
                    SELECTED.scale.y -= 0.1 * keyScale;
                }else if( event.keyCode == 188 && !event.shiftKey /*<*/){
                    SELECTED.scale.z += 0.1 * keyScale;
                }else if( event.keyCode == 188 && event.shiftKey /*SHIFT + <*/){
                    SELECTED.scale.z -= 0.1 * keyScale;
                }else if( event.keyCode == 189 /*-*/){
                    if(( keyScale < 100 && keyScale > 10 ) || keyScale == 100 ){
                        keyScale -= 10;
                    }else if(( keyScale < 10 && keyScale > 1 ) || keyScale == 10 ){
                        keyScale -= 1;
                    }else if(( keyScale < 1 && keyScale > 0.19 ) || keyScale == 1 ){
                        keyScale -= 0.1;
                    }else{
                        alert("Can't be more smaller.");
                    }
                }else if( event.keyCode == 187 /*+*/){
                    if(( keyScale < 100 && keyScale > 10 ) || keyScale == 10 ){
                        keyScale += 10;
                    }else if(( keyScale < 10 && keyScale > 1 ) || keyScale == 1 ){
                        keyScale += 1;
                    }else if(( keyScale < 1 && keyScale > 0.1 ) || keyScale == 0.1 ){
                        keyScale += 0.1;
                    }else if(( keyScale < 0.1 && keyScale > 0.01 ) || keyScale == 0.01 ){
                        keyScale += 0.01;
                    }else{
                        alert("Can't be more larger.");
                    }
                }else if( event.keyCode == 48 /*0*/){
                    keyScale = 1;
                }
            }
        }
    }

    function createSceneCommon( geometry, x, y, z, scaleX, scaleY, scaleZ, rotationX, rotationY, rotationZ) {

        zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );
        zmesh.position.set( x, y, z );
        zmesh.scale.set( scaleX, scaleY, scaleZ );
        zmesh.rotation.set(rotationX, rotationY, rotationZ);
        scene.add( zmesh );
        objects.push( zmesh );
    }
    //

    function animate() {

        requestAnimationFrame( animate );

        render();
        stats.update();

    }

    function render() {

        var delta = clock.getDelta(),
                time = clock.getElapsedTime() * 10;

        mesh.geometry.__dirtyVertices = true;

        if ( tvvideo.readyState === tvvideo.HAVE_ENOUGH_DATA ) {

            if ( tvtexture ) tvtexture.needsUpdate = true;

        }
        controls.update( delta );
        renderer.render( scene, camera );

        var distance = new THREE.Vector3(202, 135+30, -(688+48)).distanceTo(camera.position);
        tvvideo.volume = (1 - distance/800)>0?(1 - distance/800):0;
    }

</script>

</body>
</html>
